(library (file)
  (export remove-stat
          get-file
          get-filename
          get-children
          flat-children
          hidden?)
  (import (except (rnrs base) error)
          (only (guile)
                lambda* λ)
          ;; lists
          (srfi srfi-1)
          ;; strings
          (srfi srfi-13)
          ;; match-lambda
          (ice-9 match)
          ;; file-system-tree
          (ice-9 ftw)
          (alias))


  ;; from:
  ;; https://www.gnu.org/software/guile/manual/html_node/File-Tree-Walk.html
  (define remove-stat
    ;; Remove the `stat' object the `file-system-tree' provides
    ;; for each file in the tree.
    (match-lambda
      [(name stat)              ; flat file
       name]
      [(name stat children ...) ; directory
       (list name (map remove-stat children))]))


  (define get-filename
    (λ (file)
      (car file)))


  (define get-file
    (λ (filename)
      (let ([fs-tree (file-system-tree filename)])
        (match fs-tree
          [(name stat) fs-tree]
          [(name stat children ...) (list name stat)]))))


  (define hidden?
    (λ (file)
      (string-prefix? "." (get-filename file))))


  (define get-children
    (lambda* (filename #:key (hidden #t))
      (match (file-system-tree filename)
        [(name stat children ...)
         (if hidden
             (filter hidden? children)
             children)]
        [other
         '()])))


  (define flat-children
    (λ (children)
      "Turns a file system tree into merely the first layer without the
recursive children."
      (map (λ (child)
             ;; filter out its children, if it is a directory
             (match child
               ;; dir case
               [(name stat children ...)
                (list name stat)]
               ;; simple file case
               [name-and-stat name-and-stat]
               ;; what about symlinks?
               ))
           children)))


  #;(define hidden?
    (λ (file)
      "Check, whether a file is a hidden file."
      ;; assuming, that an empty filename is not possible
      (match file
        ;; dir case
        [(filename stat children ...)
         (char=? (string-ref filename 0) #\.)]
        ;; simple file case
        [(filename stat)
         (char=? (string-ref filename 0) #\.)])))
  )
